﻿//
//  Copyright © 2014 Parrish Husband (parrish.husband@gmail.com)
//  The MIT License (MIT) - See LICENSE.txt for further details.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;

namespace PiaNO
{
    /// <summary>
    /// 压缩文件信息
    /// </summary>
    public class PiaNode : ICloneable, IEquatable<PiaNode>, IEnumerable<PiaNode>
    {
        #region 成员
        /// <summary>
        /// 子节点
        /// </summary>
        IList<PiaNode>? _childNodes;

        /// <summary>
        /// 子节点
        /// </summary>
        protected internal IList<PiaNode> ChildNodes
        {
            get { return _childNodes ?? (_childNodes = new List<PiaNode>()); }
            set { _childNodes                        = value; }
        }

        /// <summary>
        /// 含有子节点
        /// </summary>
        protected internal bool HasChildNodes
        {
            get { return ChildNodes is not null && ChildNodes.Count > 0; }
        }

        /// <summary>
        /// 内部数据
        /// </summary>
        public string InnerData// 这个是不是需要隐藏?
        {
            get { return PiaSerializer.SerializeNode(this); } // 序列化节点
            set { SetInnerData(PiaSerializer.PiaFile, value); }
        }

        /// <summary>
        /// 节点名称
        /// </summary>
        public string? NodeName;

        /// <summary>
        /// 拥有者
        /// </summary>
        protected internal PiaFile? Owner;

        /// <summary>
        /// 起源
        /// </summary>
        protected internal PiaNode? Parent;

        /// <summary>
        /// 节点的属性,用键值对呈现
        /// </summary>
        public Dictionary<string, string> Values
        {
            get { return _values ??= new Dictionary<string, string>(); }
            set { _values = value; }
        }
        Dictionary<string, string>? _values;
        #endregion

        #region 构造

        /// <summary>
        /// 节点
        /// </summary>
        // protected internal PiaNode()
        public PiaNode()
        {
            ChildNodes = new List<PiaNode>();// 子节点
            Values     = new Dictionary<string, string>();
        }

        /// <summary>
        /// 内部数据
        /// </summary>
        /// <param name="innerData">内部数据</param>
        public PiaNode(string? innerData)
        {
            if (innerData == null)
                throw new ArgumentNullException(nameof(innerData));

            ChildNodes = new List<PiaNode>();// 子节点
            Values = new Dictionary<string, string>();
            this.DeserializeNode(innerData);
        }

        #endregion

        #region 方法


        /// <summary>
        /// 设置节点数据
        /// </summary>
        /// <param name="piaNode">节点</param>
        /// <param name="vla">数据</param>
        void SetInnerData(PiaNode? piaNode, string vla)
        {
            piaNode?.DeserializeNode(vla); // 反序列节点
        }

        /// <summary>
        /// 修改节点属性值
        /// </summary>
        /// <param name="key">属性名</param>
        /// <param name="value">属性值</param>
        public void ValueChang(string key, string value)
        {
            var newValue = new Dictionary<string, string>(); // 总的
            foreach (var item in Values)
            {
                if (item.Key == key)
                    newValue.Add(key, value);
                else
                    newValue.Add(item.Key, item.Value);
            }
            Values = newValue;
        }


        /// <summary>
        /// 清空所有节点数据
        /// </summary>
        public void Clear()
        {
            Values.Clear();
            ChildNodes.Clear();// 主要清空这个
        }

        /// <summary>
        /// 获取节点值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        protected internal string GetValue(string key)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("key");

            if (!Values.ContainsKey(key))
                Values.Add(key, string.Empty);

            return Values[key];
        }

        /// <summary>
        /// 设置节点值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        protected internal void SetValue(string key, string value)
        {
            if (string.IsNullOrEmpty(key))
                throw new ArgumentNullException("key");

            if (!Values.ContainsKey(key))
                Values.Add(key, value);
            else
                Values[key] = value;
        }

        /// <summary>
        /// 获取颜色
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected internal static Color? GetColor(string input)
        {
            var colorVal = int.Parse(input);
            if (colorVal == -1)
                return null;

            return Color.FromArgb(colorVal);
        }

        #endregion

        #region 重载运算符_比较
        public override bool Equals(object? obj)
        {
            return this == obj as PiaNode;
        }
        public bool Equals(PiaNode? b)
        {
            return this == b;
        }

        public static bool operator !=(PiaNode? a, PiaNode? b)
        {
            return !(a == b);
        }

        public static bool operator ==(PiaNode? a, PiaNode? b)
        {
            if (b is null)
                return (a is null);
            else if (a is null)
                return false;
            if (ReferenceEquals(a, b))// 同一个对象
                return true;

            return a.NodeName?.ToLower() == b.NodeName?.ToLower();
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        #endregion

        #region 重写/实现接口
        /// <summary>
        /// 重写下标
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public virtual PiaNode? this[string name]
        {
            get
            {
                if (ChildNodes == null || ChildNodes.Count == 0)
                    return null;

                return ChildNodes.FirstOrDefault(n =>
                        name.Equals(n.NodeName, StringComparison.InvariantCultureIgnoreCase));
            }
        }

        public override string ToString()
        {
            if (NodeName is null)
                return string.Empty;
            return NodeName;
        }

        /// <summary>
        /// ICloneable 可克隆的,浅克隆
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            return this.MemberwiseClone();
        }
        #endregion

        #region 迭代器
        public IEnumerator<PiaNode> GetEnumerator()
        {
            return ChildNodes.GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
        #endregion
    }
}
